home *** CD-ROM | disk | FTP | other *** search
/ CD/PC Actual 3 / CD ACTUAL 3.iso / linux / incoming / libgr-2.000 / libgr-2 / libgr-2.0.3 / rle / rle_open_f.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-08-14  |  4.8 KB  |  218 lines

  1. /* 
  2.  * rle_open_f.c - Open a file with defaults.
  3.  * 
  4.  * Author :     Jerry Winters 
  5.  *         EECS Dept.
  6.  *         University of Michigan
  7.  * Date:    11/14/89
  8.  * Copyright (c) 1990, University of Michigan
  9.  */
  10.  
  11. #include "rle_config.h"
  12. #include <stdio.h>
  13.  
  14. #ifndef NO_OPEN_PIPES
  15. /* Need to have a SIGCLD signal catcher. */
  16. #include <signal.h>
  17. #include <sys/wait.h>
  18. /* Do versions still exist without SIGCLD or SIGCHLD? */
  19. #ifndef SIGCLD
  20. #ifdef SIGCHLD
  21. #define SIGCLD    SIGCHLD
  22. #endif
  23. #endif
  24.  
  25. static int catching_children = 0;
  26. static void catch_child();
  27. #endif /* !NO_OPEN_PIPES */
  28.  
  29.  
  30. /* 
  31.  *  Purpose : Open a file for input or ouput as controlled by the mode
  32.  *  parameter.  If no file name is specified (ie. file_name is null) then
  33.  *  a pointer to stdin or stdout will be returned.  The calling routine may
  34.  *  call this routine with a file name of "-".  For this case rle_open_f
  35.  *  will return a pointer to stdin or stdout depending on the mode.
  36.  *    If the user specifies a non-null file name and an I/O error occurs
  37.  *  when trying to open the file, rle_open_f will terminate execution with
  38.  *  an appropiate error message.
  39.  *
  40.  *  parameters
  41.  *   input:
  42.  *     prog_name:     name of the calling program.
  43.  *     file_name :     name of the file to open
  44.  *     mode :         either "r" for read or input file or "w" for write or
  45.  *                    output file
  46.  *
  47.  *   output:
  48.  *     a file pointer
  49.  * 
  50.  */
  51. FILE *
  52. rle_open_f_noexit( prog_name, file_name, mode ) 
  53. char *prog_name, *file_name, *mode;
  54. {
  55.     FILE *fp;
  56.     void perror();
  57.     CONST_DECL char *err_str;
  58.     register char *cp;
  59.     char *combuf;
  60.  
  61. #ifdef STDIO_NEEDS_BINARY
  62.     char mode_string[32];    /* Should be enough. */
  63.  
  64.     /* Concatenate a 'b' onto the mode. */
  65.     mode_string[0] = mode[0];
  66.     mode_string[1] = 'b';
  67.     strcpy( mode_string + 2, mode + 1 );
  68.     mode = mode_string;
  69. #endif
  70.  
  71.     if ( *mode == 'w' || *mode == 'a' )
  72.     fp = stdout;     /* Set the default value */
  73.     else
  74.     fp = stdin;
  75.     
  76.     if ( file_name != NULL && strcmp( file_name, "-" ) != 0 )
  77.     {
  78. #ifndef    NO_OPEN_PIPES
  79. #ifdef    SIGCLD
  80.     /* If first time, create SIGCLD catcher. */
  81.     if ( !catching_children )
  82.     {
  83.         (void)signal( SIGCLD, catch_child );
  84.         catching_children++;
  85.     }
  86. #endif    /* SIGCLD */
  87.  
  88.     /*  Real file, not stdin or stdout.  If name ends in ".Z",
  89.      *  pipe from/to un/compress (depending on r/w mode).
  90.      *  
  91.      *  If it starts with "|", popen that command.
  92.      */
  93.  
  94.     cp = file_name + strlen( file_name ) - 2;
  95.     /* Pipe case. */
  96.     if ( *file_name == '|' )
  97.     {
  98.         if ( (fp = popen( file_name + 1, mode )) == NULL )
  99.         {
  100.         err_str = "%s: can't invoke <<%s>> for %s: ";
  101.         goto err;
  102.         }
  103.     }
  104.  
  105.     /* Compress case. */
  106.     else if ( cp > file_name && *cp == '.' && *(cp + 1) == 'Z' )
  107.     {
  108.         combuf = (char *)malloc( 20 + strlen( file_name ) );
  109.         if ( combuf == NULL )
  110.         {
  111.         err_str = "%s: out of memory opening (compressed) %s for %s";
  112.         goto err;
  113.         }
  114.  
  115.         if ( *mode == 'w' )
  116.         sprintf( combuf, "compress > %s", file_name );
  117.         else if ( *mode == 'a' )
  118.         sprintf( combuf, "compress >> %s", file_name );
  119.         else
  120.         sprintf( combuf, "compress -d < %s", file_name );
  121.  
  122.         fp = popen( combuf, mode );
  123.         free( combuf );
  124.  
  125.         if ( fp == NULL )
  126.         {
  127.         err_str =
  128.     "%s: can't invoke 'compress' program, trying to open %s for %s";
  129.         goto err;
  130.         }
  131.     }
  132.  
  133.     /* Ordinary, boring file case. */
  134.     else
  135. #endif /* !NO_OPEN_PIPES */
  136.         if ( (fp = fopen(file_name, mode)) == NULL )
  137.         {
  138.         err_str = "%s: can't open %s for %s: ";
  139.         goto err;
  140.         }
  141.     }
  142.  
  143.     return fp;
  144.  
  145. err:
  146.     fprintf( stderr, err_str,
  147.          prog_name, file_name,
  148.          (*mode == 'w') ? "output" :
  149.          (*mode == 'a') ? "append" :
  150.          "input" );
  151.     perror( "" );
  152.     return NULL;
  153.  
  154. }
  155.  
  156. FILE *
  157. rle_open_f( prog_name, file_name, mode )
  158. char *prog_name, *file_name, *mode;
  159. {
  160.     FILE *fp;
  161.  
  162.     if ( (fp = rle_open_f_noexit( prog_name, file_name, mode )) == NULL )
  163.     exit( -1 );
  164.  
  165.     return fp;
  166. }
  167.  
  168.  
  169. /*****************************************************************
  170.  * TAG( rle_close_f )
  171.  * 
  172.  * Close a file opened by rle_open_f.  If the file is stdin or stdout,
  173.  * it will not be closed.
  174.  * Inputs:
  175.  *     fd:    File to close.
  176.  * Outputs:
  177.  *     None.
  178.  * Assumptions:
  179.  *     fd is open.
  180.  * Algorithm:
  181.  *     If fd is NULL, just return.
  182.  *     If fd is stdin or stdout, don't close it.  Otherwise, call fclose.
  183.  */
  184. void
  185. rle_close_f( fd )
  186. FILE *fd;
  187. {
  188.     if ( fd == NULL || fd == stdin || fd == stdout )
  189.     return;
  190.     else
  191.     fclose( fd );
  192. }
  193.  
  194.  
  195. #ifndef NO_OPEN_PIPES
  196. #ifdef SIGCLD
  197. /* Signal handler to clean up child processes when forking. */
  198.  
  199. static void
  200. catch_child()
  201. {
  202.     /* Assume, if WNOHANG is defined, that wait3 is available. */
  203. #ifdef WNOHANG
  204.     pid_t pid;
  205.     union wait *status;
  206.     
  207.     /* Wait3 returns 0 when no more children. */
  208.     while ( wait3( &pid, &status, WNOHANG ) > 0 )
  209.     ;
  210. #else    /* !WNOHANG */
  211.     /* Must be a System V setup. Wait for the child. */
  212.     (void)wait( NULL );
  213.     signal( SIGCLD, catch_child );
  214. #endif    /* WNOHANG */
  215. }
  216. #endif /* SIGCLD */
  217. #endif /* !NO_OPEN_PIPES */
  218.